package middleware

import (
	"errors"
	"github.com/golang-jwt/jwt/v4"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/rest"
	"github.com/zeromicro/go-zero/rest/httpx"
	"net/http"
	"strconv"
	"strings"
	"yangming-college/app/usercenter/cmd/v1/rpc/pb"
	"yangming-college/app/usercenter/cmd/v1/rpc/usercenter"
)

func AuthHandle(userRpc usercenter.UserCenter, AccessSecret string) rest.Middleware {
	return func(next http.HandlerFunc) http.HandlerFunc {
		return func(w http.ResponseWriter, r *http.Request) {
			token := r.Header.Get("Authorization")
			if !checkoutPath(r.URL.Path) {
				next(w, r)
				return
			}
			// 解析token
			cl, err := jwt.Parse(token, func(token *jwt.Token) (i interface{}, e error) {
				return []byte(AccessSecret), nil
			})
			if err != nil {
				logx.Errorf("鉴权失败：%v", err)
				httpx.Error(w, errors.New("鉴权失败"))
				return
			}
			// 获取用户ID
			sub, ok := cl.Claims.(jwt.MapClaims)
			if !ok {
				logx.Errorf("鉴权失败，断言错误")
				httpx.Error(w, errors.New("鉴权失败"))
				return
			}
			// 通过用户ID获取用户角色
			roleID, err := userRpc.GetUserRole(r.Context(), &pb.UserInfoRequest{
				Id: int64(sub["uid"].(float64)),
			})

			uidStr := strconv.FormatInt(int64(sub["uid"].(float64)), 10)
			r.Header.Set("user_id", uidStr)

			//如果roleID == 7，则账号为超级管理员账号，跳过鉴权。
			if roleID.RoleId == 7 {
				next(w, r)
				return
			}

			if err != nil {
				logx.Errorf("鉴权失败，获取用户信息失败：%v", err)
				httpx.Error(w, errors.New("鉴权失败"))
				return
			}
			obj := r.URL.Path
			act := r.Method
			// 鉴权
			_, err = userRpc.Auth(r.Context(), &pb.AuthReq{
				Sub: roleID.String(),
				Obj: obj,
				Act: act,
			})
			if err != nil {
				logx.Errorf("权限不足：%v", err)
				httpx.Error(w, errors.New("权限不足"))
				return
			}

			next(w, r)
		}
	}
}

func checkoutPath(p string) bool {
	//路径上带sunshine的不走鉴权
	if strings.Contains(p, "/sunshine") {
		return false
	}
	return true
}
